﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Subjects;
using System.Reflection;
using System.Text;

namespace TfL
{
    /// <summary>
    /// A factory class for obtaining various feeds from the Tfl tube update system
    /// This system is located at http://cloud.tfl.gov.uk/TrackerNet/
    /// More information can be found at http://wiki.opentfl.co.uk/TrackerNet
    /// </summary>
    public class TrackerNet
    {
        /// <summary>
        /// Create a trackernet instance
        /// </summary>
        /// <param name="url">the tfl trackernet url</param>
        /// <param name="ns">the trackernet api namespace</param>
        /// <example>
        /// TfL.TrackerNet tracker = new TrackerNet("http://cloud.tfl.gov.uk/TrackerNet/", "http://webservices.lul.co.uk/");
        /// </example>
        public TrackerNet(string url ,string ns)
        {
            Url = url;
            Ns = ns;
        }

        public TrackerNet()
        {
            Url = "http://cloud.tfl.gov.uk/TrackerNet/";
            Ns = "http://webservices.lul.co.uk/";
        }
        /// <summary>
        /// The trackernet url
        /// </summary>
        public string Url { get; set; }
        /// <summary>
        /// The trackernet namespace
        /// </summary>
        public string Ns { get; private set; }
        /// <summary>
        /// return a feed to the trackernet station status
        /// mapped to
        /// http://cloud.tfl.gov.uk/TrackerNet/StationStatus
        /// </summary>
        public StationStatusFeed StationStatus
        {
            get { return new StationStatusFeed(Url,Ns); }
        }
        /// <summary>
        /// return a feed to the trackernet line status
        /// mapped to 
        /// http://cloud.tfl.gov.uk/TrackerNet/LineStatus
        /// </summary>
        public LineStatusFeed LineStatus
        {
            get { return new LineStatusFeed(Url, Ns); }
        }
        /// <summary>
        /// return a feed to the trackernet train prediction service
        /// mapped to
        /// http://cloud.tfl.gov.uk/TrackerNet/PredictionSummary/{line}
        /// </summary>
        /// <param name="line">The line of interest. For a list of vaild line names, use <see cref="LineCodes"/></param>
        /// <returns>an <see cref="ISubject{TrainTimesForStation,TrainTimesForStation}"/></returns>
        public TrainTimesFeed TrainTimes(string line)
        {
            return new TrainTimesFeed(Url,"",line);
        }
        /// <summary>
        /// returns a feed to the trackernet train prediction service
        /// mapped to 
        /// http://cloud.tfl.gov.uk/TrackerNet/PredictionSummary/{line}/Station
        /// for all lines
        /// </summary>
        /// <param name="station">The station of interest. For a list of valid station names, use <see cref="StationNameFeed"/></param>
        /// <returns>an <see cref="ISubject{TrainTimesForStation,TrainTimesForStation}"/></returns>
        public StationTrainTimesFeed StationArrivals(string station)
        {
            return new StationTrainTimesFeed(Url, "", station);
        }
        /// <summary>
        /// returns a feed to the trackernet train prediction service
        /// mapped to  
        /// http://cloud.tfl.gov.uk/TrackerNet/PredictionSummary/{line}
        /// for all lines
        /// Feed is filtered to return <see cref="StationName"/>
        /// </summary>
        public StationNameFeed StationNames
        {
            get { return new StationNameFeed(Url, ""); }
        }

        public StationLocation StationCoordinates(string station)
        { 
            Assembly assembly = Assembly.GetExecutingAssembly();
            var locations = StationLocation.Load(assembly.GetManifestResourceStream("TfL.LondonUnderground.xml"));
            return (from StationLocation loc in locations
                            where loc.Name.Contains(station.ToUpper())
                            select loc).FirstOrDefault();
            

        }

    }
}
